#include "ThreadPool.h"

ThreadPool::ThreadPool(size_t threadNum, const std::string& threadType):stop_(false), threadType_(threadType)
{
    //创建threadNum个线程
    for(int idx = 0; idx < threadNum; idx++)
    {
        //用lambda函数创建线程
        threads_.emplace_back([this]{
            printf("created %s thread(%ld).\n", threadType_.c_str(), syscall(SYS_gettid));   //显示线程ID

            while(stop_ == false)
            {
                std::function<void()> task;

                {//锁作用域
                    std::unique_lock<std::mutex> lock(this->mutex_);

                    //等待生产者的条件变量
                    this->condition_.wait(lock, [this]{
                        return ((this->stop_ == true) || (this->taskqueue_.empty() == false));
                    });
                    //如果任务队列中还有任务，执行完再退出
                    if((this->stop_ == true) && (this->taskqueue_.empty() == true)) return;

                    //出队一个任务
                    task = std::move(this->taskqueue_.front());
                    this->taskqueue_.pop();
                }//锁释放，解锁

                // printf("%s(%ld)execute task.\n", threadType_.c_str(), syscall(SYS_gettid));
                task();//执行任务
            }
        });
    }
}

void ThreadPool::addtask(std::function<void()> task)
{
    {//锁作用域开始
        std::lock_guard<std::mutex> lock(mutex_);
        taskqueue_.push(task);
    }//锁作用域结束

    condition_.notify_one();//唤醒一个线程
}

//停止线程
void ThreadPool::stop()
{
    if(stop_) return;

    stop_ = true;
    condition_.notify_all();    //唤醒全部线程

    //等待全部线程执行完再退出
    for(std::thread &th:threads_)
    {
        th.join();
    }
}

ThreadPool::~ThreadPool()
{
    stop();
}

size_t ThreadPool::size()
{
    return threads_.size();
}